iT邦幫忙

2022 iThome 鐵人賽

DAY 26
0
Mobile Development

【Kotlin Notes And JetPack】Build an App系列 第 26

Day 26.【DI】Hilt 的介紹與應用

  • 分享至 

  • xImage
  •  

如果對 DI 有些了解的人大概都碰過,不管是使用 Dagger 還是 Koin,今天就要來介紹 Hilt,以下如有解釋不清或是描述錯誤的地方還請大家多多指教:

什麼?

介紹 hilt 之前要先了解一下什麼是 DI,DI 也就是 Dependency Injection,將要使用的物件透過外部注入的方式給另一個 class 做使用,避免在 class 中直接 new 物件,這樣有什麼好處呢?

  • 可分離每個物件的依附性,降低偶合度
  • 較容易 debug,依附性太高,會花較多時間在盤查哪裡的 code 出錯
  • 較容易寫測試,因為元件分離,可個別測試單一元件的實作邏輯,由外部注入測試資料,測試當個 class 的邏輯即可

而 Hilt 是以 Dagger 為基礎的 DI 框架,它透過 anotention 簡化了 Dagger 的 Component 的實作,原先需手動建立的檔案由 Hilt 產生。

如何?

Android Studio 版本要 Arctic Fox or higher

| Set up

project 的 build.gradle 設置 dependency

buildscript {
    ...
    ext.hilt_version = '2.41'
    dependencies {
        ...
        classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"
    }
}

module 的 build.gradle

apply plugin: 'dagger.hilt.android.plugin'
...

dependencies {
    implementation "com.google.dagger:hilt-android:$hilt_version"
    kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
}

| Application

anotention 自己建立的 application class

@HiltAndroidApp
class WeathApplication : Application() {
    companion object {
        var instance: WeathApplication by Delegates.notNull()
    }

    override fun onCreate() {
        super.onCreate()
        instance = this
    }
}

| Activity and Fragment

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
	...
}

Warning:
 Hilt does not support retained fragments.

| ViewModel

@HiltViewModel
class MainViewModel: ViewModel()

db 透過 inject 的方式帶入 viewModel :

@HiltViewModel
class MainViewModel @Inject constructor(
    private val db: CityDAO,
	private val api: WeathbyService
): ViewModel()

| Module

為 db 建立 Module,透過 Module 來跟 hilt 做綁定

@InstallIn(SingletonComponent::class)
@Module
object DatabaseModule {

    @Singleton
    @Provides
    fun provideDB(app: Application): CityDatabase = CityDatabase.getInstance(app)

    @Singleton
    @Provides
    fun provideCityDao(db: CityDatabase): CityDAO = db.cityDao()

}

API 的部分稍微修改了原本的寫法:

  • Retrofit
object WeathbyRetrofit {
   ...
    // origin
    fun makeRetrofitService(): WeathbyService {
        return Retrofit.Builder()
            .addConverterFactory(MoshiConverterFactory.create(moshi))
            .baseUrl(BASE_URL)
            .client(client)
            .build().create(WeathbyService::class.java)
    }

	// edit
    fun makeRetrofitService(): Retrofit {
        return Retrofit.Builder()
            .addConverterFactory(MoshiConverterFactory.create(moshi))
            .baseUrl(BASE_URL)
            .client(client)
            .build()
    }
}
  • Module
@InstallIn(SingletonComponent::class)
@Module
object NetworkModule {

    @Singleton
    @Provides
    fun provideApi(): WeathbyService {
        return WeathbyRetrofit
            .makeRetrofitService()
            .create(WeathbyService::class.java)
    }
}

rebuild 完可以正常運行就成功了優

Reference

Hilt codelab


上一篇
Day 25.【UI】App Widget 新體驗
下一篇
Day 27.【Test】Unit Test 的介紹與應用
系列文
【Kotlin Notes And JetPack】Build an App30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言